<template>
   <div class="toc-container">
     <h2>目录</h2>
     <Navigation @select="handleSelect" :list="tocWithSelect"/>
   </div>
</template>

<script>
import Navigation from '../Navigation'
import { debounce } from '../../../../utils'

export default {
  name: 'index',
  components: {
    Navigation
  },
  props: {
    toc: {
      type: Array,
      default: () => []
    }
  },
  created () {
    this.setSelectDebounce = debounce(this.setSelect, 150)
    this.$bus.$on('mainScroll', this.setSelectDebounce)
  },
  data () {
    return {
      select: 'article-md-title-1' // 激活的锚链接id
    }
  },
  computed: {
    tocWithSelect () {
      // 筛选toc数组，设置选中的属性
      const getToc = (toc = []) => {
        return toc.map((item) => ({
          ...item,
          isSelect: item.anchor === this.select,
          children: getToc(item.children)
        }))
      }
      return getToc(this.toc)
    },
    doms () {
      // 获取每一个标题的dom元素
      const doms = []
      // eslint-disable-next-line no-unused-vars
      const addRoDoms = (toc = []) => {
        for (const i of toc) {
          doms.push(document.getElementById(i.anchor))
          if (i.children && i.children.length) {
            addRoDoms(i.children)
          }
        }
      }
      addRoDoms(this.toc)
      return doms
    }
  },
  methods: {
    handleSelect (item) {
      // 文章锚链接的跳转
      location.hash = item.anchor
    },
    setSelect (selectDom) {
      if (!selectDom) {
        return
      }
      // 为滚动提供事件，
      this.select = '' // 先清空在从新选中
      const range = 200 // 规定的距离
      for (const dom of this.doms) {
        if (!dom) {
          continue
        }
        const top = dom.getBoundingClientRect().top // 得到元素到视口顶边的距离
        // 在离上方规定的范围内
        if (top >= 0 && top <= range) {
          this.select = dom.id
          return
        } else if (top > range) {
          // 在规定范围内上方
          return
        } else {
          // 在规定范围内下方
          this.select = dom.id
        }
      }
    }
  },
  destroyed () {
    this.$bus.$off('mainScroll', this.setSelectDebounce)
  }
}
</script>

<style lang="less" scoped>
.toc-container{
  width: 100%;
  h2{
    font-size: 1em;
    font-weight: bold;
    letter-spacing: 2px;
    margin: 0;
  }
}
</style>
